package com.aliyun.messagemgt.application.service.Impl;


import com.aliyun.messagemgt.application.service.ChannelNoServer;
import com.aliyun.messagemgt.dto.ChannelNo;
import com.aliyun.messagemgt.dto.query.ChannelNoQuery;
import com.aliyun.messagemgt.domain.repository.ChannelNoRepository;
import com.aliyun.messagemgt.common.errorcode.CommonErrorCode;
import com.aliyun.messagemgt.common.exceptions.BaseException;
import jxl.Sheet;
import jxl.Workbook;
import jxl.read.biff.BiffException;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.dao.DataAccessException;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.annotation.Resource;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

@Service
public class ChannelNoServerImpl implements ChannelNoServer {
    private static Logger logger = LoggerFactory.getLogger(ChannelNoServerImpl.class);
    @Resource
    ChannelNoRepository channelNoRepository;

    @Override
    public Object delChannelNo(ChannelNoQuery channelNoQuery) {
        if (channelNoQuery.getChannelUserId()==null){
            throw new BaseException(CommonErrorCode.COMMON_PARAM_INVALID);
        }
        int i = channelNoRepository.delChannelNo(channelNoQuery);
        if (i<1){
            throw new BaseException(CommonErrorCode.FAIL_DELETE);
        }
        return i;
    }

    /**
     * 隐藏/显示渠道号
     * @param channelNoQuery
     * @return
     */
    @Override
    public Object hiddenChannelNo(ChannelNoQuery channelNoQuery) {
        if (channelNoQuery.getChannelUserId()==null||channelNoQuery.getHiddenState()==null){
            throw new BaseException(CommonErrorCode.COMMON_PARAM_INVALID);
        }
        int i = channelNoRepository.hiddenChannelNo(channelNoQuery);
        if (i<1){
            throw new BaseException(CommonErrorCode.FAIL_DELETE);
        }
        return i;
    }

    /**
     * 修改手机号/邮箱
     * @param channelNo
     * @return
     */
    @Override
    public Object modChannelNo(ChannelNo channelNo) {
        if (channelNo.getChannelUserId()==null){
            throw new BaseException(CommonErrorCode.COMMON_PARAM_INVALID);
        }
        int i = channelNoRepository.modChannelNo(channelNo);
        if (i<1){
            throw new BaseException(CommonErrorCode.FAIL_UPDATE);
        }
        return i;
    }

    @Override
    public Object detailChannelNo(ChannelNoQuery channelNo) {
        return channelNoRepository.detailChannelNo(channelNo);
    }

    @Override
    public Object inExcel(MultipartFile file) throws IOException, DataAccessException {
        InputStream in = null;
        in = file.getInputStream();
        List<Map> list = readExcel(in);
        in.close();
        int i = 0;
        if (list.size()>0){
            list.remove(0);
            //校验手机号和邮箱
            matchMobileAndEmail(list);
            //导入数据库
            i = channelNoRepository.insertUserInfoList(list);
        }
        if (i<1){
            throw new BaseException(CommonErrorCode.EXCEL_UPDATE);
        }
        return i;
    }

    private void matchMobileAndEmail(List<Map> list) {
        String regexMobile = "^((13[0-9])|(15[^4,\\D])|(18[0,5-9]))\\d{8}$";
        String regexEmail = "^([\\w-\\.]+)@((\\[[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.)|(([\\w-]+\\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\\]?)$";
        for (Map map : list) {
            String userMobile = (String) map.get("userMobile");
            if (!StringUtils.isEmpty(userMobile)){
                boolean match = match(regexMobile, userMobile);
                if (!match){
                    throw new BaseException(CommonErrorCode.MOBILE_TYPE_ERROR);
                }
            }
            String email = (String) map.get("officeEmail");
            if (!StringUtils.isEmpty(email)){
                boolean match = match(regexEmail, email);
                if (!match){
                    throw new BaseException(CommonErrorCode.EMAIL_TYPE_ERROR);
                }
            }
        }
    }

    private static boolean match(String regex, String str) {
        Pattern pattern = Pattern.compile(regex);
        Matcher matcher = pattern.matcher(str);
        return matcher.matches();
    }

    public List<Map> readExcel(InputStream is) {
        try {
            // jxl提供的Workbook类
            Workbook wb = Workbook.getWorkbook(is);
            // Excel的页签数量
            int sheetSize = wb.getNumberOfSheets();
            List<Map> outerList=new ArrayList<>();
            for (int index = 0; index < sheetSize; index++) {
                // 每个页签创建一个Sheet对象
                Sheet sheet = wb.getSheet(index);
                // sheet.getRows()返回该页的总行数
                for (int i = 0; i < sheet.getRows(); i++) {
                    Map innerList=new HashMap();
                    // sheet.getColumns()返回该页的总列数
                    for (int j = 0; j < sheet.getColumns(); j++) {
                        String cellinfo = sheet.getCell(j, i).getContents();
                        if(StringUtils.isEmpty(cellinfo)){
                            continue;
                        }
                        innerList.put(j,cellinfo);
                        logger.info(cellinfo);
                    }
                    Map map = dealMap(innerList);
                    if (map!=null&&map.size()>0){
                        outerList.add(map);
                    }
                }
            }
            return outerList;
        } catch (FileNotFoundException e) {
           logger.error("readExcel FileNotFoundException:",e);
        } catch (BiffException e) {
            logger.error("readExcel BiffException:",e);
        } catch (IOException e) {
            logger.error("readExcel IOException:",e);
        }
        return null;
    }

    private Map dealMap(Map map) {
        String [] str = {"userName","userPoliceId","userType","userPartType",
                "orgCode","orgName","userSex","userMobile","officeEmail"};
        try {
            for (int i = 0 ;i<str.length ; i++) {
                if (map.get(i)==null){
                    continue;
                }
                map.put(str[i],map.get(i));
                map.remove(i);
            }
            return map;
        }catch (Exception e){
            throw new BaseException(CommonErrorCode.FILE_TYPE_FAIL);
        }

    }
}
